home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / fax / ps250 / tools / fax_print.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  10.0 KB  |  481 lines

  1. /* fax_print.c: print given file of p2 or ia5 on fax printer */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/fax/ps250/tools/RCS/fax_print.c,v 6.0 1991/12/18 20:08:25 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/fax/ps250/tools/RCS/fax_print.c,v 6.0 1991/12/18 20:08:25 jpo Rel $
  9.  *
  10.  * $Log: fax_print.c,v $
  11.  * Revision 6.0  1991/12/18  20:08:25  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16. #include "util.h"
  17. #include "chan.h"
  18. #include <stdio.h>
  19. #include "../../faxgeneric.h"
  20. #include "../ps250.h"
  21. #include <varargs.h>
  22. #include <isode/cmd_srch.h>
  23. #include "retcode.h"
  24. #include "IOB-types.h"
  25.  
  26. #define    OPT_P2    1
  27. #define OPT_IA5    2
  28. #define OPT_FAX    3
  29. #define OPT_FILE 4
  30. #define OPT_SOFTCAR 5
  31. #define OPT_RES_7_7    6
  32. #define OPT_RES_3_85    7
  33. #define    OPT_RES_15_4    8
  34.  
  35. CMD_TABLE    tbl_options [] = { /* rfc822norm commandline options */
  36.     "-p2",    OPT_P2,
  37.     "-ia5",    OPT_IA5,
  38.     "-fax",    OPT_FAX,
  39.     "-file",OPT_FILE,
  40.     "-softcar", OPT_SOFTCAR,
  41.     "-3.85", OPT_RES_3_85,
  42.     "-7.7",    OPT_RES_7_7,
  43.     "-15.4", OPT_RES_15_4,
  44.     0,        -1
  45.     };
  46.  
  47. int    isP2 = TRUE;
  48. char    *file = NULLCP;
  49. int    res;
  50.  
  51. #ifndef lint
  52. void    advise (va_alist)
  53. va_dcl
  54. {
  55.         int     code;
  56.         va_list ap;
  57.  
  58.         va_start (ap);
  59.  
  60.         code = va_arg (ap, int);
  61.  
  62.         _ll_log (pp_log_norm, code, ap);
  63.  
  64.         va_end (ap);
  65. }
  66. #else
  67. /* VARARGS3 */
  68.  
  69. void    advise (code, what, fmt)
  70. char   *what,
  71.        *fmt;
  72. int     code;
  73. {
  74.         advise (code, what, fmt);
  75. }
  76. #endif
  77.  
  78. #define ps_advise(ps, f) \
  79.         advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s",\
  80.                 (f), ps_error ((ps) -> ps_errno))
  81.  
  82. extern FaxCtlr    *init_faxctrlr();
  83. extern int    fax_debug;
  84. CHAN    *mychan = NULLCHAN;
  85. int    table_verified = FALSE;
  86.  
  87. main (argc, argv)
  88. int    argc;
  89. char    **argv;
  90. {
  91.     FILE    *fp;
  92.     FaxCtlr    *faxctl = init_faxctrlr();
  93.     PsModem    *psm = PSM(faxctl);
  94.  
  95.     sys_init (argv[0]);
  96.     *argv++;
  97.     while    (*argv != NULL) {
  98.         switch (cmd_srch(*argv, tbl_options)) {
  99.             case OPT_P2:
  100.             isP2 = TRUE;
  101.             break;
  102.             case OPT_IA5:
  103.             isP2 = FALSE;
  104.             break;
  105.             case OPT_FAX:
  106.             if (*(argv+1) == NULLCP) {
  107.                 fprintf(stderr,
  108.                     "no fax device given with flag '%s'\n",*argv);
  109.                 exit(1);
  110.             }
  111.             argv++;
  112.             sprintf(psm->devName, "%s", *argv);
  113.             break;
  114.  
  115.             case OPT_FILE:
  116.             if (*(argv+1) == NULLCP) {
  117.                 fprintf(stderr,
  118.                     "no file given with flag '%s'\n",*argv);
  119.                 exit(1);
  120.             }
  121.             argv++;
  122.             file = *argv;    
  123.             break;
  124.             
  125.             case OPT_SOFTCAR:
  126.             psm->softcar = TRUE;
  127.             break;
  128.  
  129.             case OPT_RES_3_85:
  130.             res = RES_3_85;
  131.             break;
  132.  
  133.             case OPT_RES_7_7:
  134.             res = RES_7_7;
  135.             break;
  136.  
  137.             case OPT_RES_15_4:
  138.             res = RES_15_4;
  139.             break;
  140.  
  141.             default:
  142.             fprintf(stderr,
  143.                 "unknown option '%s'\n", *argv);
  144.             exit(1);
  145.         }
  146.         argv++;
  147.     }
  148.  
  149.     if (file != NULLCP) {
  150.         if (isP2
  151.             && (fp = fopen (file, "r")) == (FILE *)0) {
  152.             fprintf(stderr,
  153.                 "Can't open file '%s'\n", file);
  154.         exit(1);
  155.         }
  156.     } else
  157.         fp = stdin;
  158.         
  159.     
  160.     if (faxctl->open != NULLIFP
  161.         && (*faxctl->open) (faxctl) != OK) {
  162.         fprintf(stderr,
  163.             "fax open failed [%s]\n",
  164.             faxctl->errBuf);        
  165.         if (faxctl->close != NULLIFP)
  166.             (*faxctl->close)(faxctl);
  167.         exit(1);
  168.     }
  169.  
  170.     sprintf (faxctl -> telno, "0");
  171.  
  172.         if (faxctl->initXmit != NULLIFP
  173.             && rp_isbad((*faxctl->initXmit)(faxctl))) {
  174.         if (faxctl -> abort != NULLIFP)
  175.             (*faxctl->abort) (faxctl);
  176.         fprintf(stderr,
  177.             "unable to initialise fax device for printing [%s]\n",
  178.             faxctl->errBuf);       
  179.         if (faxctl->close != NULLIFP)
  180.             (*faxctl->close)(faxctl);
  181.         exit(1);
  182.     }
  183.  
  184.     if (isP2) 
  185.         print_P2(faxctl, fp);
  186.     else
  187.         print_ia5(faxctl, file);
  188.     
  189.     if (faxctl->close !=  NULLIFP)
  190.         (*faxctl->close) (faxctl);
  191.     
  192.     if (file != NULLCP) fclose(fp);
  193.         
  194. }
  195.  
  196. /*   */
  197.  
  198. print_P2 (faxctl, fp)
  199. FaxCtlr    *faxctl;
  200. FILE    *fp;
  201. {
  202.     register PE     pe = NULLPE;
  203.         register PS     psin;
  204.     struct type_IOB_G3FacsimileBodyPart    *g3fax = NULL;
  205.  
  206.     if ((psin = ps_alloc (std_open)) == NULLPS)
  207.         {
  208.                 ps_advise (psin, "ps_alloc");
  209.         if (faxctl -> abort != NULLIFP)
  210.             (*faxctl->abort) (faxctl);
  211.         if (faxctl->close != NULLIFP)
  212.             (*faxctl->close)(faxctl);
  213.                 exit(1);
  214.         }
  215.  
  216.     if (std_setup (psin, fp) == NOTOK)
  217.         {
  218.                 ps_free (psin);
  219.                 advise (LLOG_EXCEPTIONS, NULLCP, "%s: std_setup loses", file);
  220.         if (faxctl -> abort != NULLIFP)
  221.             (*faxctl->abort) (faxctl);
  222.         if (faxctl->close != NULLIFP)
  223.             (*faxctl->close)(faxctl);
  224.                 exit(1);
  225.         }
  226.  
  227.     if (do_decode_fax(psin, &g3fax) == NOTOK) {
  228.         fprintf(stderr,
  229.                "failed to decode G3FacsimileBodyPart\n");
  230.                 ps_done(psin, "ps2pe");
  231.         if (faxctl -> abort != NULLIFP)
  232.             (*faxctl->abort) (faxctl);
  233.         if (faxctl->close != NULLIFP)
  234.             (*faxctl->close)(faxctl);
  235.         exit(1);
  236.         }
  237.  
  238.         if (g3fax->parameters
  239.             && faxctl->setG3Params != NULLIFP
  240.             && (*faxctl->setG3Params)(faxctl, g3fax->parameters) != OK) {
  241.                 fprintf(stderr,
  242.             "setG3Params failed [%s]", faxctl->errBuf);
  243.                 return RP_MECH;
  244.         }
  245.  
  246.  
  247.     if (fax_bitstrings (faxctl, g3fax, TRUE) != OK) {
  248.         fprintf(stderr,
  249.             "Failed to fax bitstrings\n");
  250.         
  251.         if (faxctl->close != NULLIFP)
  252.             (*faxctl->close)(faxctl);
  253.         exit(1);
  254.     }
  255.     if (pe != NULLPE)
  256.                 pe_free (pe);
  257. }
  258.  
  259. /* 
  260.  * send each page of g3fax to fax machine 
  261.  */
  262.  
  263. static int fax_bitstrings (faxctl, g3fax, last)
  264. FaxCtlr    *faxctl;
  265. struct type_IOB_G3FacsimileBodyPart    *g3fax;
  266. int last;
  267. {
  268.     struct type_IOB_G3FacsimileData    *ix;
  269.     int retval;
  270.     
  271.     for (ix = g3fax -> data; ix != NULL; ix = ix -> next) {
  272.         int        len;
  273.         char    *str;
  274.  
  275.         if ((str = bitstr2strb (ix -> element_IOB_0, &len)) == NULLCP) {
  276.             fprintf(stderr,"empty page");
  277.             return NOTOK;
  278.         }
  279.         len = (len + BITSPERBYTE -1)/BITSPERBYTE;
  280.  
  281.         retval = faxctl->sendPage(faxctl, str, len, 
  282.                       (last && ix -> next == NULL));
  283.         free (str);
  284.         if (retval != OK)
  285.             return retval;
  286.     }
  287.     return  OK;
  288. }
  289.  
  290. print_ia5 (faxctl, file)
  291. FaxCtlr    *faxctl;
  292. char    *file;
  293. {
  294.         if (faxctl->setIA5Params != NULLIFP
  295.             && (*faxctl->setIA5Params) (faxctl) != OK) {
  296.                 PP_LOG(LLOG_EXCEPTIONS,
  297.                        ("setIA5Params failed [%s]",
  298.                         faxctl->errBuf));
  299.                 return RP_MECH;
  300.         }
  301.         
  302.         if ((*faxctl->sendIA5File)(faxctl, file, TRUE) != OK) {
  303.         if (faxctl -> abort != NULLIFP)
  304.             (*faxctl->abort) (faxctl);
  305.         fprintf(stderr,
  306.             "sendIA5File failed [%s]",
  307.             faxctl->errBuf);
  308.         if (faxctl->close != NULLIFP)
  309.             (*faxctl->close)(faxctl);
  310.         exit(1);
  311.     }
  312. }
  313.  
  314.  
  315. /* 
  316.  * decode from PE to C struct
  317.  */
  318. extern PE    ps2pe_aux ();
  319.  
  320. static int do_decode_fax (psin, pfax)
  321. register PS    psin;
  322. struct type_IOB_G3FacsimileBodyPart    **pfax;
  323. {
  324.     struct type_IOB_G3FacsimileData        *new, *tail = NULL;
  325.     int                    pages;
  326.     register PE                 pe = NULLPE;
  327.     
  328.     /* get first chunk */
  329.     if ((pe = ps2pe_aux (psin, 1, 0)) == NULLPE) {
  330.         ps_done (psin, "ps2pe_aux");
  331.         return NOTOK;
  332.     }
  333.     
  334.     if ((PE_ID(pe -> pe_class, pe -> pe_id) !=  
  335.          PE_ID(PE_CLASS_UNIV, PE_CONS_SEQ))
  336.         && (PE_ID(pe -> pe_class, pe -> pe_id) !=
  337.         PE_ID(PE_CLASS_CONT, (PElementID) 0x03))) {
  338.         PP_LOG(LLOG_EXCEPTIONS,
  339.                ("Unexpected pe in G3FacsimileBodyPart: expected sequence"));
  340.         return NOTOK;
  341.     }
  342.     
  343.     pe_free (pe);
  344.  
  345.     *pfax = (struct type_IOB_G3FacsimileBodyPart *) calloc (1,
  346.                                    sizeof (struct type_IOB_G3FacsimileBodyPart));
  347.     
  348.     /* get and decode parameters */
  349.     if ((pe = ps2pe (psin)) == NULLPE) { /* EOF or error? */
  350.         ps_done (psin, "ps2pe");
  351.         return NOTOK;
  352.         }
  353.         PY_pepy[0] = 0;
  354.  
  355.     if (decode_IOB_G3FacsimileParameters(pe, 1, 
  356.                         NULLIP, NULLVP, 
  357.                         &((*pfax) -> parameters)) == NOTOK) {
  358.         PP_LOG(LLOG_EXCEPTIONS,
  359.                ("decode_IOB_G3FacsimileParameters failure [%s]",
  360.             PY_pepy));
  361.         pe_done(pe, "Parse failure IOB_G3FacsimileParameters");
  362.         return NOTOK;
  363.     }
  364.     
  365.     if (PY_pepy[0] != 0)
  366.         PP_LOG(LLOG_EXCEPTIONS,
  367.                ("parse_IOB_G3FacsimileParameters non fatal failure [%s]",
  368.                         PY_pepy));
  369.  
  370.     pe_free (pe);
  371.  
  372.     /* get next chunk */
  373.     if ((pe = ps2pe_aux (psin, 1, 0)) == NULLPE) {
  374.         ps_done (psin, "ps2pe_aux");
  375.         return NOTOK;
  376.     }
  377.     
  378.     if (PE_ID(pe -> pe_class, pe -> pe_id) != 
  379.         PE_ID(PE_CLASS_UNIV, PE_CONS_SEQ)) {
  380.         PP_LOG(LLOG_EXCEPTIONS,
  381.                ("Unexpected pe in G3FacsimileBodyPart: expected sequence"));
  382.         return NOTOK;
  383.     }
  384.  
  385.     pe_free (pe);
  386.     
  387.     pages = 0;
  388.     while ((pe = ps2pe (psin)) != NULLPE) {
  389.         switch (PE_ID(pe -> pe_class, pe -> pe_id)) {
  390.             case PE_ID (PE_CLASS_UNIV, PE_PRIM_BITS):
  391.             break;
  392.             case PE_ID (PE_CLASS_UNIV, PE_UNIV_EOC) :
  393.             pe_free(pe);
  394.             continue;
  395.             default:
  396.             PP_LOG(LLOG_EXCEPTIONS,
  397.                    ("Unexpected pe in G3FacsimileBodyPart: expected bitstring"));
  398.             return NOTOK;
  399.         }
  400.         new = (struct type_IOB_G3FacsimileData *) (calloc (1,
  401.                                   sizeof(struct type_IOB_G3FacsimileData)));
  402.         new -> element_IOB_0 = prim2bit(pe);
  403.         if ( (*pfax) -> data == NULL)
  404.             (*pfax) -> data = tail = new;
  405.         else {
  406.             tail -> next = new;
  407.             tail = tail -> next;
  408.         }
  409.         pages++;
  410.     }
  411.     
  412.     if ((*pfax) -> parameters -> optionals == opt_IOB_G3FacsimileParameters_number__of__pages
  413.         && (*pfax) -> parameters -> number__of__pages != pages) {
  414.         PP_LOG(LLOG_EXCEPTIONS, 
  415.                ("Incorrect number of pages in G3FacsimileBodyPart: expected %d, got %d",
  416.             (*pfax) -> parameters -> number__of__pages, pages));
  417.         return NOTOK;
  418.     }
  419.     return OK;
  420. }
  421.  
  422. /* 
  423.  * various isode-like routines
  424.  */
  425.  
  426. /* pe_done: utility routine to do the right thing for pe errors */
  427. int             pe_done (pe, msg)
  428. PE              pe;
  429. char            *msg;
  430. {
  431.         if (pe->pe_errno)
  432.         {
  433.                 PP_OPER(NULLCP,
  434.                         ("%s: [%s] %s",msg,PY_pepy,pe_error(pe->pe_errno)));
  435.                 pe_free (pe);
  436.                 return NOTOK;
  437.         }
  438.         else
  439.         {
  440.                 pe_free (pe);
  441.                 return OK;
  442.         }
  443. }
  444.  
  445. /* ps_done: like pe_done */
  446. int             ps_done (ps, msg)
  447. PS              ps;
  448. char           *msg;
  449. {
  450.         ps_advise (ps, msg);
  451.         ps_free (ps);
  452.         return NOTOK;
  453. }
  454.  
  455. #ifndef lint
  456. void    adios (va_alist)
  457. va_dcl
  458. {
  459.         va_list ap;
  460.  
  461.         va_start (ap);
  462.  
  463.         _ll_log (pp_log_norm, LLOG_FATAL, ap);
  464.  
  465.         va_end (ap);
  466.  
  467.         _exit (1);
  468. }
  469. #else
  470. /* VARARGS2 */
  471.  
  472. void    adios (what, fmt)
  473. char   *what,
  474.        *fmt;
  475. {
  476.         adios (what, fmt);
  477. }
  478. #endif
  479.  
  480.  
  481.